import mqtt from "mqtt";
import App from "./app";
// import { load } from "./app";
// import html2canvas from "html2canvas";

/**
 * 获取唯一数字
 * @returns {number}
 */
function uniqueNumber() {
  let date = Date.now();
  if (date <= uniqueNumber.previous) {
    date = ++uniqueNumber.previous;
  } else {
    uniqueNumber.previous = date;
  }
  return date;
}
export default class BimMap {
  /**
   * 初始化
   *
   */
  constructor() {
    this.param = {
      // 模型集合
      modelLayers: [],

      // 参数化模型绑定事件
      labelEventMap: {},

      // 标签集合
      labelMap: new Map(),

      // 自定义DIV标签集合
      divLabels: {},

      // 自定义DIV标签移动状态
      divIsMoving: false,

      // 内置事件
      hookGroup: Math.random(),
    };
    this.domId = "";
    this.taskId = null;
    this.sceneType = "";
    this.ws = {
      send: () => {},
      close: () => {},
    };
    this.dataChannel = {
      send: () => {},
      sendAndReceive: () => {},
      close: () => {},
    };
    this.webJson = null;
    this.Hook = {
      hooks: [],
      add(name, callback, group, once) {
        let id = uniqueNumber();
        this.hooks.push({
          id,
          name,
          once,
          group,
          callback,
        });
        return id;
      },
      addOnce(name, callback) {
        return this.add(name, callback, undefined, true);
      },
      run(name, a, b, c, d, e, f, g) {
        for (let i = 0; i < this.hooks.length; i++) {
          let h = this.hooks[i];
          if (h.name === name) {
            try {
              if (typeof h.callback === "function") {
                h.callback(a, b, c, d, e, f, g);
              }
            } catch (e) {
              console.error(e);
            }
            if (h.once) {
              this.hooks.splice(i--, 1);
            }
          }
        }
      },
      remove(...id) {
        for (let i = 0; i < this.hooks.length; i++) {
          if (id.indexOf(this.hooks[i].id) >= 0) {
            this.hooks.splice(i--, 1);
          }
        }
      },
      removeByGroup(group) {
        for (let i = 0; i < this.hooks.length; i++) {
          if (this.hooks[i].group === group) {
            this.hooks.splice(i--, 1);
          }
        }
      },
    };
  }

  /**
   * 初始化数据通道
   * @param {String} taskId 任务ID
   */
  initDataChannel(taskId, url) {
    let _this = this;
    let client = null;
    //判断当前浏览器是否支持WebSocket
    if ("WebSocket" in window) {
      client = mqtt.connect(url + "/" + taskId);
      client.subscribe("event-" + taskId, { qos: 1 });
      // client.subscribe("#");
    } else {
      console.error("Not support websocket");
      return null;
    }
    // 连接成功回调
    client.on("connect", function () {
      // console.log("mqtt=================onopen==================")
    });
    //断开连接后回调
    client.on("close", function () {
      // console.log("mqtt=================onclose==================")
    });
    //连接错误回调
    client.on("error", function () {
      // console.log("mqtt=================onerror==================")
    });
    //接收到消息的回调方法
    client.on("message", (topic, message) => {
      // console.log(message);
      // console.log(String.fromCharCode.apply(null, message));
      const dataString = String.fromCharCode.apply(null, message);
      if (dataString.indexOf("handle") < 0) {
        return;
      }
      let data = JSON.parse(dataString);
      // console.log('mqtt-DataChannel', topic, data);
      if (data.handle === "CoordinateConvert") {
        let position = data.params.position;
        let powerX = 0;
        let powerY = 0;
        let playerDom = document.querySelector("#" + this.domId);
        let containerSon =
          _this.container.getElementsByTagName("video")[0] ||
          _this.container.getElementsByTagName("iframe")[0];
        if (this.webJson?.initWinSize) {
          switch (this.webJson?.initWinSize) {
            case "0":
              if (
                playerDom.scrollWidth / playerDom.scrollHeight >
                containerSon.videoWidth / containerSon.videoHeight
              ) {
                powerX =
                  (playerDom.scrollWidth -
                    (containerSon.videoWidth * playerDom.scrollHeight) /
                      containerSon.videoHeight) *
                  (position.x - 0.5);
              } else {
                powerY =
                  (playerDom.scrollHeight -
                    (containerSon.videoHeight * playerDom.scrollWidth) /
                      containerSon.videoWidth) *
                  (position.y - 0.5);
              }
              break;
            case "2":
              if (
                playerDom.scrollWidth / playerDom.scrollHeight >
                containerSon.videoWidth / containerSon.videoHeight
              ) {
                powerX =
                  (playerDom.scrollWidth -
                    (containerSon.videoWidth * playerDom.scrollHeight) /
                      containerSon.videoHeight) *
                  (position.x - 0.5);
              } else {
                powerY =
                  (playerDom.scrollHeight -
                    (containerSon.videoHeight * playerDom.scrollWidth) /
                      containerSon.videoWidth) *
                  (position.y - 0.5);
              }
              break;
            case "4":
              break;
            default:
              break;
          }
        }
        let scrollHeight = containerSon.scrollHeight;
        let scrollWidth = containerSon.scrollWidth;
        data.params.position = {
          x: position.x * scrollWidth - powerX,
          y: position.y * scrollHeight - powerY,
        };
      }
      this.Hook.run(data.handle, data.params);
      if (
        typeof data.params === "object" &&
        Object.prototype.hasOwnProperty.call(data, "messageId")
      ) {
        this.Hook.run(data.messageId, data.params);
      }
    });

    // 生成唯一ID
    let getGuid = this.tool.guid;
    return {
      // 发送消息
      send(handle, params, messageId) {
        let message = {
          handle,
          params,
        };
        if (messageId) {
          message.messageId = messageId;
        }
        // if (taskId) {
        //     message.taskId = taskId
        // }
        // console.log(message);
        client.publish("action-" + taskId, JSON.stringify(message), { qos: 1 });
        // websocket.send(JSON.stringify(message));
      },
      // 发送并接收
      sendAndReceive(handle, params, callback) {
        params = params || {};
        let messageId = getGuid();
        // this.Hook.addOnce(params.messageId, callback);
        console.time(messageId);
        _this.Hook.addOnce(messageId, (...data) => {
          callback(...data);
        });
        this.send(handle, params, messageId);
      },
      // 关闭连接
      close() {
        client.end();
        // websocket.close();
      },
    };
  }
  createAEC(option) {
    let configArr = ["domId", "taskId", "renderJson", "webJson"];
    let optionArr = Object.keys(option);
    if (
      optionArr.filter((item) => {
        return configArr.indexOf(item) > -1;
      }).length !== configArr.length
    ) {
      console.error("createScene接受参数有误");
      return;
    }
    let sonId = option.domId + "-son";
    let sonDom = document.createElement("div");
    sonDom.id = sonId;
    let dom = document.getElementById(option.domId);
    this.domId = option.domId;
    dom.appendChild(sonDom);
    option.sonId = sonId;
    this.taskId = option.taskId;
    option.webJson = JSON.parse(option.webJson);
    if (Object.keys(option.webJson).length == 0) {
      option.webJson = null;
    }
    this.webJson = option.webJson;
    //默认wsUrl
    if (!option.wsUrl) {
      const defaultWsUrl =
        (location.protocol === "http:" ? "ws:" : "wss:") +
        "//" +
        location.host +
        "/api/app/ws/player/" +
        option.taskId;
      option.wsUrl = defaultWsUrl;
    }
    //默认mqttUrl
    if (!option.mqttUrl) {
      const defaultMqttUrl =
        (location.protocol === "http:" ? "ws:" : "wss:") +
        "//" +
        location.host +
        "/mqtt";
      option.mqttUrl = defaultMqttUrl;
    }
    //初始化ue
    let app = new App();
    this.ws = app.load(option, this.Hook);
    // 初始化数据通道
    this.dataChannel = this.initDataChannel(this.taskId, option.mqttUrl);
    // 初始化三维引擎
    this.container = document.getElementById(this.domId);
    // 初始化事件监听
    this.initEvent();
  }
  createPXY(option) {
    let configArr = ["domId", "appUrl"];
    let optionArr = Object.keys(option);
    if (
      optionArr.filter((item) => {
        return configArr.indexOf(item) > -1;
      }).length !== configArr.length
    ) {
      console.error("createScene接受参数有误");
      return;
    }
    let sonDom = document.createElement("iframe");
    sonDom.style.width = "100%";
    sonDom.style.height = "100%";
    let dom = document.getElementById(option.domId);
    this.domId = option.domId;
    dom.appendChild(sonDom);

    //默认mqttUrl
    if (!option.mqttUrl) {
      const defaultMqttUrl =
        (location.protocol === "http:" ? "ws:" : "wss:") +
        "//" +
        location.host +
        "/mqtt";
      option.mqttUrl = defaultMqttUrl;
    }
    // 初始化数据通道
    this.dataChannel = this.initDataChannel(this.taskId, option.mqttUrl);
    // 初始化三维引擎
    this.container = document.getElementById(this.domId);
    sonDom.contentWindow.location.href = option.appUrl;
    // 初始化事件监听
    this.initEvent();
  }
  createGYY(option) {
    let configArr = ["domId", "appUrl"];
    let optionArr = Object.keys(option);
    if (
      optionArr.filter((item) => {
        return configArr.indexOf(item) > -1;
      }).length !== configArr.length
    ) {
      console.error("createScene接受参数有误");
      return;
    }
    let sonDom = document.createElement("iframe");
    sonDom.style.width = "100%";
    sonDom.style.height = "100%";
    let dom = document.getElementById(option.domId);
    this.domId = option.domId;
    dom.appendChild(sonDom);
    this.taskId = this.tool.getUrlParam(option.appUrl, "taskId");
    //默认mqttUrl
    if (!option.mqttUrl) {
      const defaultMqttUrl =
        (location.protocol === "http:" ? "ws:" : "wss:") +
        "//" +
        location.host +
        "/mqtt";
      option.mqttUrl = defaultMqttUrl;
    }
    window.addEventListener("message", (params) => {
      // 初始化数据通道
      if (params?.data?.type === 10) {
        console.log(params.data.data.taskid);
        this.dataChannel = this.initDataChannel(
          params.data.data.taskid,
          option.mqttUrl
        );
        this.taskId = params.data.data.taskid;
      }
    });
    // 初始化三维引擎
    this.container = document.getElementById(this.domId);
    sonDom.contentWindow.location.href = option.appUrl;
    // 初始化事件监听
    this.initEvent();
  }
  /**
   * 创建场景
   * @param {{}=} option 配置含 taskId,wsUrl,mqttUrl,domId,renderJson
   */
  createScene(option) {
    this.sceneType = option.type;
    switch (option.type) {
      case "AEC":
        this.createAEC(option);
        break;
      case "PXY":
        this.createPXY(option);
        break;
      case "GYY":
        this.createGYY(option);
        break;
      default:
        break;
    }
  }

  /**
   * 初始化事件监听
   */
  initEvent() {
    // 应用连接消息
    this.Hook.add(
      "connectInfo",
      (params) => {
        this.Hook.run("info", {
          type: "connectInfo",
          content: params,
        });
      },
      this.param.hookGroup
    );
    // 应用超时
    this.Hook.add(
      "timeout",
      () => {
        this.dataChannel.close();
        this.ws.send(
          JSON.stringify({
            type: "timeout",
            taskId: this.taskId,
          })
        );
      },
      this.param.hookGroup
    );
    // 注销应用
    this.Hook.add(
      "TaskDestroy",
      () => {
        this.destroy();
      },
      this.param.hookGroup
    );
    // 视点变更, 更新标签位置
    this.Hook.add(
      "CameraInfo",
      () => {
        if (!this.param.divIsMoving) {
          this.param.divIsMoving = true;
          Object.keys(this.param.divLabels).forEach((id) => {
            setTimeout(() => {
              this.updateModelPosition(id);
            });
          });
          this.param.divIsMoving = false;
        }
      },
      this.param.hookGroup
    );
  }

  /**
   * 销毁场景
   */
  destroy() {
    this.ws.close();
    this.dataChannel.close();
    this.Hook.removeByGroup(this.param.hookGroup);
  }

  /**
   * 显隐所有模型
   * @param {boolean} show 是否显示
   * @param {string|string[]=} filter 要排除的pmtsId
   */
  showAllPmts(show, filter) {
    if (typeof filter === "undefined" || !filter) {
      filter = [];
    } else if (filter.constructor !== Array) {
      filter = [filter];
    }
    this.param.modelLayers.forEach((modelLayer) => {
      modelLayer.isShow = filter.indexOf(modelLayer.id) > -1 ? !show : show;
    });
  }

  /**
   * 添加参数化建模
   * @param type {string} 类型
   * @param option {{}} 参数
   * @param id {string=} 可选，若无则自动创建
   */
  addModel(type, option, id) {
    let guid = "";
    let rmcb = undefined;
    switch (type) {
      case "Label":
        guid = this.engine.plotLayer.appendDynamicBillboardPlot(option);
        rmcb = this.engine.plotLayer.addEventListener(guid, (eventType) => {
          if (eventType === "click") {
            this.Hook.run("EntityClick", {
              id: guid,
              type: type,
            });
          }
        });
        id = option.id ? option.id : guid;
        this.param.labelMap.set(id, guid);
        guid = id;
        break;
      case "DivLabel":
        // {
        //     show: true,
        //     position: this.tool.tc([106, 29, 100]),
        //     minDistance: 0,
        //     maxDistance: 100000,
        //     divId: "",
        // };
        guid = option.id || id || this.tool.guid();
        option.id = guid;
        option.minDistance = option.minDistance || 0;
        option.dom = document.getElementById(option.divId);
        option.show = typeof option.show === "undefined" ? true : option.show;
        this.param.divLabels[guid] = option;
        this.updateModelPosition(guid);
        break;
      default:
        break;
    }
    this.param.labelEventMap[guid] = {
      type,
      removeEvent: rmcb,
    };
    return guid;
  }

  /**
   * 显隐标签
   * @param {string} id 标签ID
   * @param {boolean} show 是否显示
   */
  showModel(id, show) {
    let label = this.param.labelEventMap[id];
    if (!label) {
      return;
    }
    if ("DivLabel" === label.type) {
      this.param.divLabels[id].show = show;
      this.param.divLabels[id].dom.style.display = show ? "block" : "none";
    } else if (["Label"].indexOf(label.type) > -1) {
      this.engine.plotLayer.setShowPlot(show, this.param.labelMap.get(id));
    } else if (["Polygon"].indexOf(label.type) > -1) {
      console.log(1);
    }
  }

  /**
   * 删除标签
   * @param id
   */
  removeModel(id) {
    let label = this.param.labelEventMap[id];
    if (!label) {
      return;
    }
    if ("DivLabel" === label.type) {
      this.showModel(id, false);
      delete this.param.divLabels[id];
    } else if (["Label"].indexOf(label.type) > -1) {
      this.engine.plotLayer.removeDynamicPlot(this.param.labelMap.get(id));
      label.removeEvent();
    }
    delete this.param.labelEventMap[id];
  }

  /**
   * 更新标签位置
   * @param {string} id 标签ID
   * @param {{}=} position2 世界坐标
   */
  updateModelPosition(id, position2) {
    let label = this.param.divLabels[id];
    if (!label) {
      return;
    }
    let dom = label.dom;
    if (!dom) {
      return;
    }
    try {
      // let cameraPosition = this.engine.viewer.camera.position;
      if (position2) {
        label.position = position2;
      }
      if (!label.show) {
        return;
      }
      this.wcs2scc(label.position, (position) => {
        dom.style.left = position.x + "px";
        dom.style.top = position.y + "px";
        // if (label.show) {
        //     let distance = this.getSpaceDistance([cameraPosition, label.position]);
        //     distance = Math.round(distance);
        //     if (!label.maxDistance || (label.minDistance <= distance && distance < label.maxDistance)) {
        //         dom.style.display = 'block';
        //         dom.style.zIndex = 2147483647 - distance;
        //     } else {
        //         dom.style.display = 'none';
        //     }
        // }
      });
    } catch (e) {
      dom.style.display = "none";
    }
  }

  /**
   * 屏幕截图
   */
  captureScreen(width = 400, height = 400, callback) {
    var dom = document.querySelector("#" + this.domId); // 获取idDom
    var video = dom.getElementsByTagName("video")[0];
    let canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height;
    canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
    let dataUrl = canvas.toDataURL();
    callback(dataUrl);
  }
  /**
   * 获取当前视点
   */
  getCurrentCameraInfo(callback) {
    this.dataChannel.sendAndReceive("GetCameraInfo", {}, (params) => {
      callback(params);
    });
  }

  /**
   * 设置当前视点
   */
  setCurrentCameraInfo(cameraInfo, duration) {
    if (typeof cameraInfo === "undefined" || !cameraInfo) {
      return;
    }
    if (cameraInfo.constructor === String) {
      cameraInfo = cameraInfo.split(",");
      cameraInfo = cameraInfo.map((c) => Number(c));
    }
    if (typeof duration === "undefined") {
      duration = 0;
    }
    this.dataChannel.send("SetCameraInfo", {
      cameraInfo,
      duration,
    });
  }
  /**
   * 设置相机路线
   */
  setCameraPath(params) {
    this.dataChannel.send("SetCameraFromPath", params);
  }
  /**
   * 绘制相机路线
   */
  setDrawLine(params) {
    this.dataChannel.send("DrawLine", params);
  }
  /**
   * 图标操作CIM2.0（绘制相机路线点位）
   */
  setControlIcon(params) {
    this.dataChannel.send("ControlIcon", params);
  }

  /**
   * 控制相机路线
   */
  setControlCameraPath(params) {
    this.dataChannel.send("ControlCameraPath", params);
  }
  /**
   * 编辑模式切换
   */
  setChangeEditMode(params) {
    this.dataChannel.send("ChangeEditMode", params);
  }
  /**
   * 修改剖切模式
   */
  setCutMode(params) {
    this.dataChannel.send("CutMode", params);
  }
  /**
   * 模型定位
   */
  Fly2Model(params) {
    this.dataChannel.send("Fly2Model", params);
  }
  /**
   * 模型单元控制
   */
  setModelControl(params) {
    this.dataChannel.send("ModelUnitControl", params);
  }
  /**
   * 设置模型
   */
  setUeModel(params) {
    this.dataChannel.send("SpawnItem", params);
  }
  /**
   * 场景初始化事件（数组版）
   */
  setSceneLoading(params) {
    this.dataChannel.send("SceneLoading", params);
  }
  /**
   * 模型半透明
   */
  setTransluceModel(params) {
    this.dataChannel.send("TransluceModel", params);
  }
  /**
   * 模型显隐
   */
  setDisplayModel(params) {
    this.dataChannel.send("DisplayModel", params);
  }
  /**
   * 自定义特效控制
   */
  setCustomEffectControl(params) {
    this.dataChannel.send("CustomEffectControl", params);
  }

  /**
   * 模型选中or取消
   */
  toggleCheck(modelId, componentId, flag) {
    let params = {
      modelId,
      componentId,
      // modelId: id.slice(0, id.indexOf("-")),
      // componentId: id.slice(id.indexOf("-") + 1),
      rgba: flag ? [0, 0, 0, 1] : [0, 0, 0, 0],
    };
    this.dataChannel.send("HighlightComponent", params);
  }
  /**
   * 显示控制（根据tags控制模型的显示和隐藏）
   */
  setVisbleByTags(params) {
    this.dataChannel.send("SetVisbleByTags", params);
  }

  /**
   * 开始第一人称
   */
  startFirstPerson() {
    this.dataChannel.send("OperationMode", { mode: 1 });
  }

  /**
   * 结束第一人称
   */
  stopFirstPerson() {
    this.dataChannel.send("OperationMode", { mode: 0 });
  }

  tool = (() => {
    let _this = this;
    return {
      /**
       * 获取URL中的参数值
       * @param {string} url
       * @param {string} param
       * @returns {string}
       */
      getUrlParam(url, param) {
        let reg = new RegExp("(^|&|\\?)" + param + "=([^&]*)(&|$)", "i");
        let m = url.match(reg);
        if (m == null) {
          return "";
        }
        return unescape(m[2]);
      },
      /**
       * 地理坐标转换为世界坐标
       * @param {{x,y,z}} geographic 地理坐标
       * @param {function({x,y,z})} callback 回调
       */
      tc(geographic, callback) {
        _this.dataChannel.sendAndReceive(
          "CoordinateConvert",
          {
            geographic,
          },
          (params) => {
            callback(params.coordinate);
          }
        );
      },
      /**
       * 世界坐标转换为地理坐标
       * @param {{x,y,z}} coordinate 世界坐标
       * @param {function({x,y,z})} callback 回调
       */
      tg(coordinate, callback) {
        _this.dataChannel.sendAndReceive(
          "CoordinateConvert",
          {
            coordinate,
          },
          (params) => {
            callback(params.geographic);
          }
        );
      },

      /**
       * 唯一ID
       * @returns {string}
       */
      guid() {
        return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
          /[xy]/g,
          function (c) {
            let r = (Math.random() * 16) | 0,
              v = c === "x" ? r : (r & 0x3) | 0x8;
            return v.toString(16);
          }
        );
      },

      /**
       * rgba色 转 16进制颜色转
       * @param rgbaArray
       * @param alphaMaxVal 一般这里就是1或者255 默认以1为基准 如果最大值是255 就写255
       * @returns {string}
       */
      rgbaToHexColor(rgbaArray, alphaMaxVal = 1) {
        //补位警号
        return (
          "#" +
          rgbaArray
            .map((channel, index) => {
              let hexNum = "";
              if (index === 3) {
                //这是alpha通道
                hexNum = Number(
                  Math.round((channel * 255) / alphaMaxVal)
                ).toString(16);
              } else {
                //普通通道直接转换
                hexNum = Number(channel).toString(16);
              }
              return hexNum.length === 1 ? "0" + hexNum : hexNum; //这里解决了部分通道数字小于10的情况进行补位
            })
            .join("")
        );
      },
      /**
       * 16进制颜色转 rgba色
       * @param {string} hexColor #000000
       * @param {number} alphaMaxVal 1或者255 默认1
       * @returns {string[]}
       */
      hexColorToRgba(hexColor, alphaMaxVal = 1) {
        hexColor = hexColor.replace("#", "");

        //用于分割16进制色彩通道
        let reg = new RegExp("\\w{1,2}", "g");
        //分割颜色通道
        let rgbaArray255 = hexColor.match(reg);
        rgbaArray255 = rgbaArray255.map((channel, index) => {
          //计算每个通道的10进制值
          let colorVal = parseInt(channel, 16);
          if (index === 3) {
            //这是alpha通道
            return Math.round((colorVal / (255 / alphaMaxVal)) * 100) / 100;
          }
          return colorVal;
        });
        return rgbaArray255;
      },
      /**
       * 画布截图
       * @param canvas 画布
       * @param width 输出宽度
       * @param height 输出高度
       * @param fullScreen 是否全屏/按比例
       * @returns {string}
       */
      getCanvasDataUrl(canvas, width, height, fullScreen) {
        let temp = document.createElement("canvas");
        temp.setAttribute("width", width);
        temp.setAttribute("height", height);
        let a = canvas.width;
        let o = canvas.height;
        let s, l, u, d;
        if (fullScreen) {
          s = l = 0;
          u = a;
          d = o;
        } else {
          let f = width / a;
          let c = height / o;
          if (f >= c) {
            u = a;
            d = (u * height) / width;
            s = 0;
            l = (o - d) * 0.5;
          } else {
            d = o;
            u = (d * width) / height;
            s = (a - u) * 0.5;
            l = 0;
          }
        }
        let context = temp.getContext("2d");
        context.drawImage(canvas, s, l, u, d, 0, 0, width, height);
        let dataUrl = temp.toDataURL("image/png");
        temp.remove();
        return dataUrl;
      },
    };
  })();

  /**
   * 世界坐标转换为屏幕坐标
   * @param {{x,y,z}} coordinate 世界坐标
   * @param {function({x,y})} callback 回调
   */
  wcs2scc(coordinate, callback) {
    this.dataChannel.sendAndReceive(
      "CoordinateConvert",
      {
        coordinate,
      },
      (params) => {
        callback(params.position);
      }
    );
  }
  /**
   * 获取两点直线距离
   * @param positions
   * @returns {number}
   */
  getSpaceDistance(positions) {
    let distance = 0;
    for (let i = 0; i < positions.length - 1; i++) {
      let point1 = positions[i];
      if (Array.isArray(positions[i])) {
        point1 = this.tool.tc(positions[i]);
      }
      let point2 = positions[i + 1];
      if (Array.isArray(positions[i + 1])) {
        point2 = this.tool.tc(positions[i + 1]);
      }
      /**根据世界坐标计算出距离**/
      let s = Math.sqrt(
        Math.pow(point1.x - point2.x, 2) +
          Math.pow(point1.y - point2.y, 2) +
          Math.pow(point1.z - point2.z, 2)
      );
      distance = distance + s;
    }
    return distance;
  }

  /**
   * 获取两点直线距离(根据世界坐标)
   * @param positions [{x,y,z},{x,y,z}]
   * @returns {number}
   */
  getSpaceDistanceByWorld(positions) {
    let distance = 0;
    let s = Math.sqrt(
      Math.pow(positions[0].x - positions[1].x, 2) +
        Math.pow(positions[0].y - positions[1].y, 2) +
        Math.pow(positions[0].z - positions[1].z, 2)
    );
    distance = distance + s;
    return distance;
  }
}
